GraphQL における N+1 問題の発生しやすさはデメリットなのか
Software Design 2024年9月号
LT;DR
GraphQL で N + 1 問題 が発生しやすいのは、デメリットではない
クライアントがクエリを通じて関連を簡単に解決できる利便性の結果である
REST API であっても GraphQL であっても、N + 1 問題に注意を配る必要がある
REST API の場合、実装時に N + 1 問題の発生に気が付きやすい
一方、GraphQL の場合、実装時にどのようなクエリが発行されるか完全に予測できないため、一歩先を読んだ対策が必要になる
一般的に DataLoader を用いて回避する
hr.icon
メモ
「GraphQL は N + 1 問題 が発生しやすいのがデメリット」とよく言われる
https://arc.net/l/quote/zwevmhiy
ORM と似た理屈
データベース呼び出しを透過的に行える性質上、N + 1 を注意しにくくなる
これはデメリットではなく、クライアントがクエリを通じて関連を簡単に解決できる利便性の結果 であると考える
ただ、N + 1 問題の発生には注意が必要であることには変わりない
なぜ発生しやすいか?
「全ユーザの投稿を取得する」クエリを例に考える
code:gql
query {
allUsers {
posts {
title
content
}
}
}
GraphQL サーバは内部的に、各フィールドに対して事前に定義した Resolver と呼ばれる関数を実行する
上記のケースでは、posts フィールドの Resolver がユーザの id ごとに実行される
その都度、各ユーザの投稿を取得する SQL が発行されるため N + 1 問題が発生する
N + 1 問題を解決する
一般的に、DataLoader などのライブラリを用いる
REST API の場合はどうか
同様の問題は起こり得る
が、実装時に N + 1 問題が発生するという違和感に気が付きやすい
どのようなレスポンスを返すかがはっきりしているため
一方 GraphQL は実装時にどのようなクエリが発行されるか完全に予測できないため、一歩先を読んだ対策が必要になる
リソース指向 の API 設計であれば、各ユーザのポストを取得する API 呼び出しは N 回発生する
これを解決するためには、N 回を 1 回で済ませられるようなエンドポイントの作成が必要